home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / frasrc19.zip / PARSER.C < prev    next >
Text File  |  1995-03-08  |  63KB  |  2,490 lines

  1. /* Parser.c (C) 1990, Mark C. Peterson, CompuServe [70441,3353]
  2.    All rights reserved.
  3.  
  4.    Code may be used in any program provided the author is credited
  5.     either during program execution or in the documentation.  Source
  6.     code may be distributed only in combination with public domain or
  7.     shareware source code.  Source code may be modified provided the
  8.     copyright notice and this message is left unchanged and all
  9.     modifications are clearly documented.
  10.  
  11.     I would appreciate a copy of any work which incorporates this code,
  12.     however this is optional.
  13.  
  14.     Mark C. Peterson
  15.     405-C Queen St. Suite #181
  16.     Southington, CT 06489
  17.     (203) 276-9721
  18. */
  19.  
  20. /*    Chuck Ebbert (CompuServe [76306,1226] ) changed code marked 'CAE fp'    */
  21. /*   for fast 387 floating-point math.  See PARSERA.ASM and PARSERFP.C */
  22. /*   (13 Dec 1992.)  */
  23. /* */
  24. /*   Modified 12 July 1993 by CAE to fix crash when formula not found.  */
  25.  
  26. #include <string.h>
  27. #include <ctype.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <float.h>                              /* TIW 04-22-91 */
  31. #include <time.h>
  32. #include "mpmath.h"
  33. #include "prototyp.h"
  34.  
  35.  
  36. #ifdef WATCH_MP
  37. double x1, y1, x2, y2;
  38. #endif
  39.  
  40. enum MATH_TYPE MathType = D_MATH;
  41. /* moved _LCMPLX and union ARg to mpmath.h -6-20-90 TIW */
  42.  
  43. /* PB 910417 added MAX_OPS and MAX_ARGS defines */
  44. #define MAX_ARGS 100
  45. #define MAX_OPS 250
  46. struct PEND_OP {
  47.    void (far *f)(void);
  48.    int p;
  49. };
  50. /* CAE fp added MAX_STORES and LOADS */
  51. /* MAX_STORES must be even to make Unix alignment work */
  52. #define MAX_STORES 128  /* at most only half the ops can be stores */
  53. #define MAX_LOADS  200  /* and 80% can be loads */
  54.  
  55. /* PB 901103 made some of the following static for safety */
  56. static struct PEND_OP far *o;
  57.  
  58. static void parser_allocate(void);
  59.  
  60. union Arg *Arg1, *Arg2;
  61. /* PB 910417 removed unused "a" array */
  62.  
  63. /* CAE fp  made some of the following non-static for PARSERA.ASM */
  64. /* Some of these variables should be renamed for safety */
  65. union Arg s[20], far * far *Store, far * far *Load;    /* static CAE fp */
  66. int StoPtr, LodPtr, OpPtr;    /* static CAE fp */
  67.  
  68. void (far * far *f)(void) = (void(far * far *)(void))0;    /* static CAE fp */
  69.  
  70. unsigned vsp, LastOp;    /* CAE fp made non-static */
  71. static unsigned n, ErrPtr, posp, NextOp, InitN;
  72. static int paren, SyntaxErr, ExpectingArg;
  73. struct ConstArg far *v = (struct ConstArg far *)0;    /* was static CAE fp */
  74. int InitLodPtr, InitStoPtr, InitOpPtr, LastInitOp;    /* was static CAE fp */
  75. static int Delta16;
  76. double fgLimit;           /* TIW 05-04-91 */
  77. static double fg;
  78. static int ShiftBack;     /* TIW 06-18-90 */
  79. static int SetRandom;     /* MCP 11-21-91 */
  80. static int Randomized;
  81. static unsigned long RandNum;
  82. int uses_p1, uses_p2, uses_p3;
  83.  
  84. #ifndef TESTING_MATH
  85. #define dShiftx dx1[row]
  86. #define dShifty dy1[col]
  87. #define lShiftx lx1[row]
  88. #define lShifty ly1[col]
  89. #else
  90. #define dShiftx 0.0
  91. #define dShifty 0.0
  92. #define lShiftx 0L
  93. #define lShifty 0L
  94. #endif
  95.  
  96. #define LastSqr v[4].a
  97.  
  98. static char far * far ErrStrings[] = {   /* TIW 03-31-91 added far */
  99.    "Should be an Argument",
  100.    "Should be an Operator",
  101.    "')' needs a matching '('",
  102.    "Need more ')'",
  103.    "Undefined Operator",
  104.    "Undefined Function",
  105.    "More than one ','",
  106.    "Table overflow"
  107. };
  108.  
  109. unsigned SkipWhiteSpace(char *Str) {
  110.    unsigned n, Done;
  111.  
  112.    for(Done = n = 0; !Done; n++) {
  113.       switch(Str[n]) {
  114.       case ' ':
  115.       case '\t':
  116.       case '\n':
  117.       case '\r':
  118.          break;
  119.       default:
  120.          Done = 1;
  121.       }
  122.    }
  123.    return(n - 1);
  124. }
  125.  
  126. /* use the following when only float functions are implemented to
  127.    get MP math and Integer math */
  128.    
  129. #ifndef XFRACT
  130. #define FUNCT
  131. #ifdef FUNCT /* use function form save space - isn't really slower */  
  132. static void mStkFunct(void (*fct)(void))   /* call lStk via dStk */
  133. {
  134.    Arg1->d = MPC2cmplx(Arg1->m);
  135.    (*fct)();
  136.    Arg1->m = cmplx2MPC(Arg1->d);
  137. }
  138.  
  139. static void lStkFunct(void (*fct)(void))   /* call lStk via dStk */
  140. {
  141.    double y;
  142.    /* 
  143.       intermediate variable needed for safety because of 
  144.       different size of double and long in Arg union
  145.    */
  146.    y = (double)Arg1->l.y / fg;
  147.    Arg1->d.x = (double)Arg1->l.x / fg;
  148.    Arg1->d.y = y;
  149.    (*fct)();
  150.    if(fabs(Arg1->d.x) < fgLimit && fabs(Arg1->d.y) < fgLimit) {
  151.       Arg1->l.x = (long)(Arg1->d.x * fg);
  152.       Arg1->l.y = (long)(Arg1->d.y * fg);
  153.    }
  154.    else
  155.       overflow = 1;
  156. }
  157. #else  /* use Macro form for (?) greater speed */
  158.   /* call lStk via dStk */
  159. #define mStkFunct(fct)  \
  160.    Arg1->d = MPC2cmplx(Arg1->m);\
  161.    (*fct)();\
  162.    Arg1->m = cmplx2MPC(Arg1->d);
  163.    
  164.  
  165. /* call lStk via dStk */
  166. #define lStkFunct(fct) {\
  167.    double y;\
  168.    y = (double)Arg1->l.y / fg;\
  169.    Arg1->d.x = (double)Arg1->l.x / fg;\
  170.    Arg1->d.y = y;\
  171.    (*fct)();\
  172.    if(fabs(Arg1->d.x) < fgLimit && fabs(Arg1->d.y) < fgLimit) {\
  173.       Arg1->l.x = (long)(Arg1->d.x * fg);\
  174.       Arg1->l.y = (long)(Arg1->d.y * fg);\
  175.    }\
  176.    else\
  177.       overflow = 1;\
  178. }
  179.  
  180.  
  181. #endif
  182.  
  183. #endif
  184.  
  185. /* Random number code, MCP 11-21-91 */
  186.  
  187. unsigned long NewRandNum(void)
  188. {
  189.    return(RandNum = ((RandNum << 15) + rand15()) ^ RandNum);
  190. }
  191.  
  192. void lRandom(void)
  193. {
  194.    v[7].a.l.x = NewRandNum() >> (32 - bitshift);
  195.    v[7].a.l.y = NewRandNum() >> (32 - bitshift);
  196. }
  197.  
  198. void dRandom(void)
  199. {
  200.    long x, y;
  201.  
  202.    /* Use the same algorithm as for fixed math so that they will generate
  203.       the same fractals when the srand() function is used. */
  204.    x = NewRandNum() >> (32 - bitshift);
  205.    y = NewRandNum() >> (32 - bitshift);
  206.    v[7].a.d.x = ((double)x / (1L << bitshift));
  207.    v[7].a.d.y = ((double)y / (1L << bitshift));
  208. }
  209.  
  210. #ifndef XFRACT
  211. void mRandom(void)
  212. {
  213.    long x, y;
  214.  
  215.    /* Use the same algorithm as for fixed math so that they will generate
  216.       the same fractals when the srand() function is used. */
  217.    x = NewRandNum() >> (32 - bitshift);
  218.    y = NewRandNum() >> (32 - bitshift);
  219.    v[7].a.m.x = *fg2MP(x, bitshift);
  220.    v[7].a.m.y = *fg2MP(y, bitshift);
  221. }
  222. #endif
  223.  
  224. void SetRandFnct(void)
  225. {
  226.    unsigned Seed;
  227.  
  228.    if(!SetRandom)
  229.       RandNum = Arg1->l.x ^ Arg1->l.y;
  230.  
  231.    Seed = (unsigned)RandNum ^ (unsigned)(RandNum >> 16);
  232.    srand(Seed);
  233.    SetRandom = 1;
  234.  
  235.    /* Clear out the seed */
  236.    NewRandNum();
  237.    NewRandNum();
  238.    NewRandNum();
  239. }
  240.  
  241. void RandomSeed(void)
  242. {
  243.    time_t ltime;
  244.  
  245.    /* Use the current time to randomize the random number sequence. */
  246.    time(<ime);
  247.    srand((unsigned int)ltime);
  248.  
  249.    NewRandNum();
  250.    NewRandNum();
  251.    NewRandNum();
  252.    Randomized = 1;
  253. }
  254.  
  255. #ifndef XFRACT
  256. void lStkSRand(void)
  257. {
  258.    SetRandFnct();
  259.    lRandom();
  260.    Arg1->l = v[7].a.l;
  261. }
  262. #endif
  263.  
  264. #ifndef XFRACT
  265. void mStkSRand(void)
  266. {
  267.    Arg1->l.x = Arg1->m.x.Mant ^ (long)Arg1->m.x.Exp;
  268.    Arg1->l.y = Arg1->m.y.Mant ^ (long)Arg1->m.y.Exp;
  269.    SetRandFnct();
  270.    mRandom();
  271.    Arg1->m = v[7].a.m;
  272. }
  273. #endif
  274.  
  275. void dStkSRand(void)
  276. {
  277.    Arg1->l.x = (long)(Arg1->d.x * (1L << bitshift));
  278.    Arg1->l.y = (long)(Arg1->d.y * (1L << bitshift));
  279.    SetRandFnct();
  280.    dRandom();
  281.    Arg1->d = v[7].a.d;
  282. }
  283.  
  284. void (*StkSRand)(void) = dStkSRand;
  285.  
  286. void dStkAbs(void) {
  287.    Arg1->d.x = fabs(Arg1->d.x);
  288.    Arg1->d.y = fabs(Arg1->d.y);
  289. }
  290.  
  291. #ifndef XFRACT
  292. void mStkAbs(void) {
  293.    if(Arg1->m.x.Exp < 0)
  294.       Arg1->m.x.Exp = -Arg1->m.x.Exp;
  295.    if(Arg1->m.y.Exp < 0)
  296.       Arg1->m.y.Exp = -Arg1->m.y.Exp;
  297. }
  298.  
  299. void lStkAbs(void) {
  300.    Arg1->l.x = labs(Arg1->l.x);
  301.    Arg1->l.y = labs(Arg1->l.y);
  302. }
  303. #endif
  304.  
  305. void (*StkAbs)(void) = dStkAbs;
  306.  
  307. void dStkSqr(void) {
  308.    LastSqr.d.x = Arg1->d.x * Arg1->d.x;
  309.    LastSqr.d.y = Arg1->d.y * Arg1->d.y;
  310.    Arg1->d.y = Arg1->d.x * Arg1->d.y * 2.0;
  311.    Arg1->d.x = LastSqr.d.x - LastSqr.d.y;
  312.    LastSqr.d.x += LastSqr.d.y;
  313.    LastSqr.d.y = 0;
  314. }
  315.  
  316. #ifndef XFRACT
  317. void mStkSqr(void) {
  318.    LastSqr.m.x = *MPmul(Arg1->m.x, Arg1->m.x);
  319.    LastSqr.m.y = *MPmul(Arg1->m.y, Arg1->m.y);
  320.    Arg1->m.y = *MPmul(Arg1->m.x, Arg1->m.y);
  321.    Arg1->m.y.Exp++;
  322.    Arg1->m.x = *MPsub(LastSqr.m.x, LastSqr.m.y);
  323.    LastSqr.m.x = *MPadd(LastSqr.m.x, LastSqr.m.y);
  324.    LastSqr.m.y.Mant = (long)(LastSqr.m.y.Exp = 0);
  325. }
  326.  
  327. void lStkSqr(void) {
  328.    LastSqr.l.x = multiply(Arg1->l.x, Arg1->l.x, bitshift);
  329.    LastSqr.l.y = multiply(Arg1->l.y, Arg1->l.y, bitshift);
  330.    Arg1->l.y = multiply(Arg1->l.x, Arg1->l.y, bitshift) << 1;
  331.    Arg1->l.x = LastSqr.l.x - LastSqr.l.y;
  332.    LastSqr.l.x += LastSqr.l.y;
  333.    LastSqr.l.y = 0L;
  334. }
  335. #endif
  336.  
  337. void (*StkSqr)(void) = dStkSqr;
  338.  
  339. void dStkAdd(void) {
  340.    Arg2->d.x += Arg1->d.x;
  341.    Arg2->d.y += Arg1->d.y;
  342.    Arg1--;
  343.    Arg2--;
  344. }
  345.  
  346. #ifndef XFRACT
  347. void mStkAdd(void) {
  348.    Arg2->m = MPCadd(Arg2->m, Arg1->m);
  349.    Arg1--;
  350.    Arg2--;
  351. }
  352.  
  353. void lStkAdd(void) {
  354.    Arg2->l.x += Arg1->l.x;
  355.    Arg2->l.y += Arg1->l.y;
  356.    Arg1--;
  357.    Arg2--;
  358. }
  359. #endif
  360.  
  361. void (*StkAdd)(void) = dStkAdd;
  362.  
  363. void dStkSub(void) {
  364.    Arg2->d.x -= Arg1->d.x;
  365.    Arg2->d.y -= Arg1->d.y;
  366.    Arg1--;
  367.    Arg2--;
  368. }
  369.  
  370. #ifndef XFRACT
  371. void mStkSub(void) {
  372.    Arg2->m = MPCsub(Arg2->m, Arg1->m);
  373.    Arg1--;
  374.    Arg2--;
  375. }
  376.  
  377. void lStkSub(void) {
  378.    Arg2->l.x -= Arg1->l.x;
  379.    Arg2->l.y -= Arg1->l.y;
  380.    Arg1--;
  381.    Arg2--;
  382. }
  383. #endif
  384.  
  385. void (*StkSub)(void) = dStkSub;
  386.  
  387. void dStkConj(void) {
  388.    Arg1->d.y = -Arg1->d.y;
  389. }
  390.  
  391. #ifndef XFRACT
  392. void mStkConj(void) {
  393.    Arg1->m.y.Exp ^= 0x8000;
  394. }
  395.  
  396. void lStkConj(void) {
  397.    Arg1->l.y = -Arg1->l.y;
  398. }
  399. #endif
  400.  
  401. void (*StkConj)(void) = dStkConj;
  402.  
  403. void dStkZero(void) {
  404.    Arg1->d.y = Arg1->d.x = 0.0;
  405. }
  406.  
  407. #ifndef XFRACT
  408. void mStkZero(void) {
  409.    Arg1->m.x.Mant = Arg1->m.x.Exp = 0;
  410.    Arg1->m.y.Mant = Arg1->m.y.Exp = 0;
  411. }
  412.  
  413. void lStkZero(void) {
  414.    Arg1->l.y = Arg1->l.x = 0;
  415. }
  416. #endif
  417.  
  418. void (*StkZero)(void) = dStkZero;
  419.  
  420. void dStkReal(void) {
  421.    Arg1->d.y = 0.0;
  422. }
  423.  
  424. #ifndef XFRACT
  425. void mStkReal(void) {
  426.    Arg1->m.y.Mant = (long)(Arg1->m.y.Exp = 0);
  427. }
  428.  
  429. void lStkReal(void) {
  430.    Arg1->l.y = 0l;
  431. }
  432. #endif
  433.  
  434. void (*StkReal)(void) = dStkReal;
  435.  
  436. void dStkImag(void) {
  437.    Arg1->d.x = Arg1->d.y;
  438.    Arg1->d.y = 0.0;
  439. }
  440.  
  441. #ifndef XFRACT
  442. void mStkImag(void) {
  443.    Arg1->m.x = Arg1->m.y;
  444.    Arg1->m.y.Mant = (long)(Arg1->m.y.Exp = 0);
  445. }
  446.  
  447. void lStkImag(void) {
  448.    Arg1->l.x = Arg1->l.y;
  449.    Arg1->l.y = 0l;
  450. }
  451. #endif
  452.  
  453. void (*StkImag)(void) = dStkImag;
  454.  
  455. void dStkNeg(void) {
  456.    Arg1->d.x = -Arg1->d.x;
  457.    Arg1->d.y = -Arg1->d.y;
  458. }
  459.  
  460. #ifndef XFRACT
  461. void mStkNeg(void) {
  462.    Arg1->m.x.Exp ^= 0x8000;
  463.    Arg1->m.y.Exp ^= 0x8000;
  464. }
  465.  
  466. void lStkNeg(void) {
  467.    Arg1->l.x = -Arg1->l.x;
  468.    Arg1->l.y = -Arg1->l.y;
  469. }
  470. #endif
  471.  
  472. void (*StkNeg)(void) = dStkNeg;
  473.  
  474. void dStkMul(void) {
  475.    FPUcplxmul(&Arg2->d, &Arg1->d, &Arg2->d);
  476.    Arg1--;
  477.    Arg2--;
  478. }
  479.  
  480. #ifndef XFRACT
  481. void mStkMul(void) {
  482.    Arg2->m = MPCmul(Arg2->m, Arg1->m);
  483.    Arg1--;
  484.    Arg2--;
  485. }
  486.  
  487. void lStkMul(void) {
  488.    long x, y;
  489.  
  490.    x = multiply(Arg2->l.x, Arg1->l.x, bitshift) -
  491.    multiply(Arg2->l.y, Arg1->l.y, bitshift);
  492.    y = multiply(Arg2->l.y, Arg1->l.x, bitshift) +
  493.    multiply(Arg2->l.x, Arg1->l.y, bitshift);
  494.    Arg2->l.x = x;
  495.    Arg2->l.y = y;
  496.    Arg1--;
  497.    Arg2--;
  498. }
  499. #endif
  500.  
  501. void (*StkMul)(void) = dStkMul;
  502.  
  503. void dStkDiv(void) {
  504.    FPUcplxdiv(&Arg2->d, &Arg1->d, &Arg2->d);
  505.    Arg1--;
  506.    Arg2--;
  507. }
  508.  
  509. #ifndef XFRACT
  510. void mStkDiv(void) {
  511.    Arg2->m = MPCdiv(Arg2->m, Arg1->m);
  512.    Arg1--;
  513.    Arg2--;
  514. }
  515.  
  516. void lStkDiv(void) {
  517.    long x, y, mod, x2, y2;
  518.  
  519.    mod = multiply(Arg1->l.x, Arg1->l.x, bitshift) +
  520.    multiply(Arg1->l.y, Arg1->l.y, bitshift);
  521.    x = divide(Arg1->l.x, mod, bitshift);
  522.    y = -divide(Arg1->l.y, mod, bitshift);
  523.    /* pb 900617 changed next 4 lines to use x2,y2 instead of x,y */
  524.    x2 = multiply(Arg2->l.x, x, bitshift) - multiply(Arg2->l.y, y, bitshift);
  525.    y2 = multiply(Arg2->l.y, x, bitshift) + multiply(Arg2->l.x, y, bitshift);
  526.    Arg2->l.x = x2;
  527.    Arg2->l.y = y2;
  528.    Arg1--;
  529.    Arg2--;
  530. }
  531. #endif
  532.  
  533. void (*StkDiv)(void) = dStkDiv;
  534.  
  535. void dStkMod(void) {
  536.    Arg1->d.x = (Arg1->d.x * Arg1->d.x) + (Arg1->d.y * Arg1->d.y);
  537.    Arg1->d.y = 0.0;
  538. }
  539.  
  540. #ifndef XFRACT
  541. void mStkMod(void) {
  542.    Arg1->m.x = MPCmod(Arg1->m);
  543.    Arg1->m.y.Mant = (long)(Arg1->m.y.Exp = 0);
  544. }
  545.  
  546. void lStkMod(void) {
  547. /*   Arg1->l.x = multiply(Arg2->l.x, Arg1->l.x, bitshift) + */
  548. /*   multiply(Arg2->l.y, Arg1->l.y, bitshift); */
  549. /*** I don't understand how this ever worked correctly! JCO 12/31/94 ***/
  550.    Arg1->l.x = multiply(Arg1->l.x, Arg1->l.x, bitshift) +
  551.    multiply(Arg1->l.y, Arg1->l.y, bitshift);
  552.    if(Arg1->l.x < 0)
  553.       overflow = 1;
  554.    Arg1->l.y = 0L;
  555. }
  556. #endif
  557.  
  558. void (*StkMod)(void) = dStkMod;
  559.  
  560. void StkSto(void) {
  561.    *Store[StoPtr++] = *Arg1;
  562. }
  563.  
  564. void StkLod(void) {
  565.    Arg1++;
  566.    Arg2++;
  567.    *Arg1 = *Load[LodPtr++];
  568. }
  569.  
  570. void StkClr(void) {
  571.    s[0] = *Arg1;
  572.    Arg1 = &s[0];
  573.    Arg2 = Arg1;
  574.    Arg2--;
  575. }
  576.  
  577.  
  578. /* MCP 4-9-91, Added Flip() */
  579.  
  580. void dStkFlip(void) {
  581.    double t;
  582.  
  583.    t = Arg1->d.x;
  584.    Arg1->d.x = Arg1->d.y;
  585.    Arg1->d.y = t;
  586. }
  587.  
  588. #ifndef XFRACT
  589. void mStkFlip(void) {
  590.    struct MP t;
  591.  
  592.    t = Arg1->m.x;
  593.    Arg1->m.x = Arg1->m.y;
  594.    Arg1->m.y = t;
  595. }
  596.  
  597. void lStkFlip(void) {
  598.    long t;
  599.  
  600.    t = Arg1->l.x;
  601.    Arg1->l.x = Arg1->l.y;
  602.    Arg1->l.y = t;
  603. }
  604. #endif
  605.  
  606. void (*StkFlip)(void) = dStkFlip;
  607.  
  608. void dStkSin(void) {
  609.    double sinx, cosx, sinhy, coshy;
  610.  
  611.    FPUsincos(&Arg1->d.x, &sinx, &cosx);
  612.    FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy);
  613.    Arg1->d.x = sinx*coshy;
  614.    Arg1->d.y = cosx*sinhy;
  615. }
  616.  
  617. #ifndef XFRACT
  618. void mStkSin(void) {
  619.    mStkFunct(dStkSin);   /* call lStk via dStk */
  620. }
  621.  
  622. void lStkSin(void) {
  623.    long x, y, sinx, cosx, sinhy, coshy;
  624.    x = Arg1->l.x >> Delta16;
  625.    y = Arg1->l.y >> Delta16;
  626.    SinCos086(x, &sinx, &cosx);
  627.    SinhCosh086(y, &sinhy, &coshy);
  628.    Arg1->l.x = multiply(sinx, coshy, ShiftBack); /* TIW 06-18-90 */
  629.    Arg1->l.y = multiply(cosx, sinhy, ShiftBack); /* TIW 06-18-90 */
  630. }
  631. #endif
  632.  
  633. void (*StkSin)(void) = dStkSin;
  634.  
  635. /* The following functions are supported by both the parser and for fn
  636.    variable replacement. TIW 04-22-91 */
  637.  
  638. void dStkTan(void) {
  639.    double sinx, cosx, sinhy, coshy, denom;
  640.    Arg1->d.x *= 2;
  641.    Arg1->d.y *= 2;
  642.    FPUsincos(&Arg1->d.x, &sinx, &cosx);
  643.    FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy);
  644.    denom = cosx + coshy;
  645.    if(fabs(denom) <= DBL_MIN) return;
  646.    Arg1->d.x = sinx/denom;
  647.    Arg1->d.y = sinhy/denom;
  648. }
  649.  
  650. #ifndef XFRACT
  651. void mStkTan(void) {
  652.    mStkFunct(dStkTan);   /* call lStk via dStk */
  653. }
  654.  
  655. void lStkTan(void) {
  656.    long x, y, sinx, cosx, sinhy, coshy, denom;
  657.    x = Arg1->l.x >> Delta16;
  658.    x = x << 1;
  659.    y = Arg1->l.y >> Delta16;
  660.    y = y << 1;
  661.    SinCos086(x, &sinx, &cosx);
  662.    SinhCosh086(y, &sinhy, &coshy);
  663.    denom = cosx + coshy;
  664.    if(denom == 0) return;
  665.    Arg1->l.x = divide(sinx,denom,bitshift);
  666.    Arg1->l.y = divide(sinhy,denom,bitshift);
  667. }
  668. #endif
  669.  
  670. void (*StkTan)(void) = dStkTan;
  671.  
  672. void dStkTanh(void) {
  673.    double siny, cosy, sinhx, coshx, denom;
  674.    Arg1->d.x *= 2;
  675.    Arg1->d.y *= 2;
  676.    FPUsincos(&Arg1->d.y, &siny, &cosy);
  677.    FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx);
  678.    denom = coshx + cosy;
  679.    if(fabs(denom) <= DBL_MIN) return;
  680.    Arg1->d.x = sinhx/denom;
  681.    Arg1->d.y = siny/denom;
  682. }
  683.  
  684. #ifndef XFRACT
  685. void mStkTanh(void) {
  686.    mStkFunct(dStkTanh);   /* call lStk via dStk */
  687. }
  688.  
  689. void lStkTanh(void) {
  690.    long x, y, siny, cosy, sinhx, coshx, denom;
  691.    x = Arg1->l.x >> Delta16;
  692.    x = x << 1;
  693.    y = Arg1->l.y >> Delta16;
  694.    y = y << 1;
  695.    SinCos086(y, &siny, &cosy);
  696.    SinhCosh086(x, &sinhx, &coshx);
  697.    denom = coshx + cosy;
  698.    if(denom == 0) return;
  699.    Arg1->l.x = divide(sinhx,denom,bitshift);
  700.    Arg1->l.y = divide(siny,denom,bitshift);
  701. }
  702. #endif
  703.  
  704. void (*StkTanh)(void) = dStkTanh;
  705.  
  706. void dStkCoTan(void) {
  707.    double sinx, cosx, sinhy, coshy, denom;
  708.    Arg1->d.x *= 2;
  709.    Arg1->d.y *= 2;
  710.    FPUsincos(&Arg1->d.x, &sinx, &cosx);
  711.    FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy);
  712.    denom = coshy - cosx;
  713.    if(fabs(denom) <= DBL_MIN) return;
  714.    Arg1->d.x = sinx/denom;
  715.    Arg1->d.y = -sinhy/denom;
  716. }
  717.  
  718. #ifndef XFRACT
  719. void mStkCoTan(void) {
  720.    mStkFunct(dStkCoTan);   /* call lStk via dStk */
  721. }
  722.  
  723. void lStkCoTan(void) {
  724.    long x, y, sinx, cosx, sinhy, coshy, denom;
  725.    x = Arg1->l.x >> Delta16;
  726.    x = x << 1;
  727.    y = Arg1->l.y >> Delta16;
  728.    y = y << 1;
  729.    SinCos086(x, &sinx, &cosx);
  730.    SinhCosh086(y, &sinhy, &coshy);
  731.    denom = coshy - cosx;
  732.    if(denom == 0) return;
  733.    Arg1->l.x = divide(sinx,denom,bitshift);
  734.    Arg1->l.y = -divide(sinhy,denom,bitshift);
  735. }
  736. #endif
  737.  
  738. void (*StkCoTan)(void) = dStkCoTan;
  739.  
  740. void dStkCoTanh(void) {
  741.    double siny, cosy, sinhx, coshx, denom;
  742.    Arg1->d.x *= 2;
  743.    Arg1->d.y *= 2;
  744.    FPUsincos(&Arg1->d.y, &siny, &cosy);
  745.    FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx);
  746.    denom = coshx - cosy;
  747.    if(fabs(denom) <= DBL_MIN) return;
  748.    Arg1->d.x = sinhx/denom;
  749.    Arg1->d.y = -siny/denom;
  750. }
  751.  
  752. #ifndef XFRACT
  753. void mStkCoTanh(void) {
  754.    mStkFunct(dStkCoTanh);   /* call lStk via dStk */
  755. }
  756.  
  757. void lStkCoTanh(void) {
  758.    long x, y, siny, cosy, sinhx, coshx, denom;
  759.    x = Arg1->l.x >> Delta16;
  760.    x = x << 1;
  761.    y = Arg1->l.y >> Delta16;
  762.    y = y << 1;
  763.    SinCos086(y, &siny, &cosy);
  764.    SinhCosh086(x, &sinhx, &coshx);
  765.    denom = coshx - cosy;
  766.    if(denom == 0) return;
  767.    Arg1->l.x = divide(sinhx,denom,bitshift);
  768.    Arg1->l.y = -divide(siny,denom,bitshift);
  769. }
  770. #endif
  771.  
  772. void (*StkCoTanh)(void) = dStkCoTanh;
  773.  
  774. /* The following functions are not directly used by the parser - support
  775.    for the parser was not provided because the existing parser language
  776.    represents these quite easily. They are used for fn variable support
  777.    in miscres.c but are placed here because they follow the pattern of
  778.    the other parser functions. TIW 04-22-91 */
  779.  
  780. void dStkRecip(void) {
  781.    double mod;
  782.    mod =Arg1->d.x * Arg1->d.x + Arg1->d.y * Arg1->d.y;
  783.    if(mod <= DBL_MIN) return;
  784.    Arg1->d.x =  Arg1->d.x/mod;
  785.    Arg1->d.y = -Arg1->d.y/mod;
  786. }
  787.  
  788. #ifndef XFRACT
  789. void mStkRecip(void) {
  790.    struct MP mod;
  791.    mod = *MPadd(*MPmul(Arg1->m.x, Arg1->m.x),*MPmul(Arg1->m.y, Arg1->m.y));
  792.    if(mod.Mant == 0L) return;
  793.    Arg1->m.x = *MPdiv(Arg1->m.x,mod);
  794.    Arg1->m.y = *MPdiv(Arg1->m.y,mod);
  795.    Arg1->m.y.Exp ^= 0x8000;
  796. }
  797.  
  798. void lStkRecip(void) {
  799.    long mod;
  800.    mod = multiply(Arg1->l.x,Arg1->l.x,bitshift)
  801.       + multiply(Arg1->l.y,Arg1->l.y,bitshift);
  802.    if(mod<=0L) return;
  803.    Arg1->l.x =  divide(Arg1->l.x,mod,bitshift);
  804.    Arg1->l.y = -divide(Arg1->l.y,mod,bitshift);
  805. }
  806. #endif
  807.  
  808. void StkIdent(void) { /* do nothing - the function Z */
  809. }
  810. /* End TIW 04-22-91 */
  811.  
  812. void dStkSinh(void) {
  813.    double siny, cosy, sinhx, coshx;
  814.  
  815.    FPUsincos(&Arg1->d.y, &siny, &cosy);
  816.    FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx);
  817.    Arg1->d.x = sinhx*cosy;
  818.    Arg1->d.y = coshx*siny;
  819. }
  820.  
  821. #ifndef XFRACT
  822. void mStkSinh(void) {
  823.    mStkFunct(dStkSinh);   /* call lStk via dStk */
  824. }
  825.  
  826. void lStkSinh(void) {
  827.    long x, y, sinhx, coshx, siny, cosy;
  828.  
  829.    x = Arg1->l.x >> Delta16;
  830.    y = Arg1->l.y >> Delta16;
  831.    SinCos086(y, &siny, &cosy);
  832.    SinhCosh086(x, &sinhx, &coshx);
  833.    Arg1->l.x = multiply(cosy, sinhx, ShiftBack); /* TIW 06-18-90 */
  834.    Arg1->l.y = multiply(siny, coshx, ShiftBack); /* TIW 06-18-90 */
  835. }
  836. #endif
  837.  
  838. void (*StkSinh)(void) = dStkSinh;
  839.  
  840. void dStkCos(void) {
  841.    double sinx, cosx, sinhy, coshy;
  842.  
  843.    FPUsincos(&Arg1->d.x, &sinx, &cosx);
  844.    FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy);
  845.    Arg1->d.x = cosx*coshy;
  846.    Arg1->d.y = -sinx*sinhy; /* TIW 04-25-91 sign */
  847. }
  848.  
  849. #ifndef XFRACT
  850. void mStkCos(void) {
  851.    mStkFunct(dStkCos);   /* call lStk via dStk */
  852. }
  853.  
  854. void lStkCos(void) {
  855.    long x, y, sinx, cosx, sinhy, coshy;
  856.  
  857.    x = Arg1->l.x >> Delta16;
  858.    y = Arg1->l.y >> Delta16;
  859.    SinCos086(x, &sinx, &cosx);
  860.    SinhCosh086(y, &sinhy, &coshy);
  861.    Arg1->l.x = multiply(cosx, coshy, ShiftBack); /* TIW 06-18-90 */
  862.    Arg1->l.y = -multiply(sinx, sinhy, ShiftBack); /* TIW 04-25-91 sign */
  863. }
  864. #endif
  865.  
  866. void (*StkCos)(void) = dStkCos;
  867.  
  868. /* Bogus version of cos, to replicate bug which was in regular cos till v16: */
  869.  
  870. void dStkCosXX(void) {
  871.    dStkCos();
  872.    Arg1->d.y = -Arg1->d.y;
  873. }
  874.  
  875. #ifndef XFRACT
  876. void mStkCosXX(void) {
  877.    mStkFunct(dStkCosXX);   /* call lStk via dStk */
  878. }
  879.  
  880. void lStkCosXX(void) {
  881.    lStkCos();
  882.    Arg1->l.y = -Arg1->l.y;
  883. }
  884. #endif
  885.  
  886. void (*StkCosXX)(void) = dStkCosXX;
  887.  
  888. void dStkCosh(void) {
  889.    double siny, cosy, sinhx, coshx;
  890.  
  891.    FPUsincos(&Arg1->d.y, &siny, &cosy);
  892.    FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx);
  893.    Arg1->d.x = coshx*cosy;
  894.    Arg1->d.y = sinhx*siny;
  895. }
  896.  
  897. #ifndef XFRACT
  898. void mStkCosh(void) {
  899.    mStkFunct(dStkCosh);   /* call lStk via dStk */
  900. }
  901.  
  902. void lStkCosh(void) {
  903.    long x, y, sinhx, coshx, siny, cosy;
  904.  
  905.    x = Arg1->l.x >> Delta16;
  906.    y = Arg1->l.y >> Delta16;
  907.    SinCos086(y, &siny, &cosy);
  908.    SinhCosh086(x, &sinhx, &coshx);
  909.    Arg1->l.x = multiply(cosy, coshx, ShiftBack); /* TIW 06-18-90 */
  910.    Arg1->l.y = multiply(siny, sinhx, ShiftBack); /* TIW 06-18-90 */
  911. }
  912. #endif
  913.  
  914. void (*StkCosh)(void) = dStkCosh;
  915.  
  916. /* TIW added arc functions here 11-25-94 */
  917.  
  918. void dStkASin(void) {
  919.    Arcsinz(Arg1->d, &(Arg1->d));
  920. }
  921.  
  922. #ifndef XFRACT
  923. void mStkASin(void) {
  924.    mStkFunct(dStkASin);
  925. }
  926.  
  927. void lStkASin(void) {
  928.    lStkFunct(dStkASin);
  929. }
  930. #endif
  931.  
  932. void (*StkASin)(void) = dStkASin;
  933.  
  934. void dStkASinh(void) {
  935.    Arcsinhz(Arg1->d, &(Arg1->d));
  936. }
  937.  
  938. #ifndef XFRACT
  939. void mStkASinh(void) {
  940.    mStkFunct(dStkASinh);
  941. }
  942.  
  943. void lStkASinh(void) {
  944.    lStkFunct(dStkASinh);
  945. }
  946. #endif
  947.  
  948. void (*StkASinh)(void) = dStkASinh;
  949.  
  950. void dStkACos(void) {
  951.    Arccosz(Arg1->d, &(Arg1->d));
  952. }
  953.  
  954. #ifndef XFRACT
  955. void mStkACos(void) {
  956.    mStkFunct(dStkACos);
  957. }
  958.  
  959. void lStkACos(void) {
  960.    lStkFunct(dStkACos);
  961. }
  962. #endif
  963.  
  964. void (*StkACos)(void) = dStkACos;
  965.  
  966. void dStkACosh(void) {
  967.    Arccoshz(Arg1->d, &(Arg1->d));
  968. }
  969.  
  970. #ifndef XFRACT
  971. void mStkACosh(void) {
  972.    mStkFunct(dStkACosh);
  973. }
  974.  
  975. void lStkACosh(void) {
  976.    lStkFunct(dStkACosh);
  977. }
  978. #endif
  979.  
  980. void (*StkACosh)(void) = dStkACosh;
  981.  
  982. void dStkATan(void) {
  983.    Arctanz(Arg1->d, &(Arg1->d));
  984. }
  985.  
  986. #ifndef XFRACT
  987. void mStkATan(void) {
  988.    mStkFunct(dStkATan);
  989. }
  990.  
  991. void lStkATan(void) {
  992.    lStkFunct(dStkATan);
  993. }
  994. #endif
  995.  
  996. void (*StkATan)(void) = dStkATan;
  997.  
  998. void dStkATanh(void) {
  999.    Arctanhz(Arg1->d, &(Arg1->d));
  1000. }
  1001.  
  1002. #ifndef XFRACT
  1003. void mStkATanh(void) {
  1004.    mStkFunct(dStkATanh);
  1005. }
  1006.  
  1007. void lStkATanh(void) {
  1008.    lStkFunct(dStkATanh);
  1009. }
  1010. #endif
  1011.  
  1012. void (*StkATanh)(void) = dStkATanh;
  1013.  
  1014. void dStkSqrt(void) {
  1015.  /*  Sqrtz(Arg1->d, &(Arg1->d)); */
  1016.    Arg1->d = ComplexSqrtFloat(Arg1->d.x, Arg1->d.y);
  1017. }
  1018.  
  1019. #ifndef XFRACT
  1020. void mStkSqrt(void) {
  1021.    mStkFunct(dStkSqrt);
  1022. }
  1023.  
  1024. void lStkSqrt(void) {
  1025.    /* lStkFunct(dStkSqrt); */
  1026.    Arg1->l = ComplexSqrtLong(Arg1->l.x, Arg1->l.y);
  1027. }
  1028. #endif
  1029.  
  1030. void (*StkSqrt)(void) = dStkSqrt;
  1031.  
  1032. void dStkCAbs(void) {
  1033.    Arg1->d.x = sqrt(sqr(Arg1->d.x)+sqr(Arg1->d.y));
  1034.    Arg1->d.y = 0.0;
  1035. }
  1036.  
  1037. #ifndef XFRACT
  1038. void mStkCAbs(void) {
  1039.    mStkFunct(dStkCAbs);
  1040. }
  1041.  
  1042. void lStkCAbs(void) {
  1043.    lStkFunct(dStkCAbs);
  1044. }
  1045. #endif
  1046.  
  1047. void (*StkCAbs)(void) = dStkCAbs;
  1048.  
  1049. /* TIW end arc functions 11-25-94 */
  1050.  
  1051. void dStkLT(void) {
  1052.    Arg2->d.x = (double)(Arg2->d.x < Arg1->d.x);
  1053.    Arg2->d.y = 0.0;
  1054.    Arg1--;
  1055.    Arg2--;
  1056. }
  1057.  
  1058. #ifndef XFRACT
  1059. void mStkLT(void) {
  1060.    Arg2->m.x = *fg2MP((long)(MPcmp(Arg2->m.x, Arg1->m.x) == -1), 0);
  1061.    Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  1062.    Arg1--;
  1063.    Arg2--;
  1064. }
  1065.  
  1066. void lStkLT(void) {
  1067.    Arg2->l.x = (long)(Arg2->l.x < Arg1->l.x) << bitshift; /* JCO 12/26/94 */
  1068.    Arg2->l.y = 0l;
  1069.    Arg1--;
  1070.    Arg2--;
  1071. }
  1072. #endif
  1073.  
  1074. void (*StkLT)(void) = dStkLT;
  1075.  
  1076. void dStkGT(void) {
  1077.    Arg2->d.x = (double)(Arg2->d.x > Arg1->d.x);
  1078.    Arg2->d.y = 0.0;
  1079.    Arg1--;
  1080.    Arg2--;
  1081. }
  1082.  
  1083. #ifndef XFRACT
  1084. void mStkGT(void) {
  1085.    Arg2->m.x = *fg2MP((long)(MPcmp(Arg2->m.x, Arg1->m.x) == 1), 0);
  1086.    Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  1087.    Arg1--;
  1088.    Arg2--;
  1089. }
  1090.  
  1091. void lStkGT(void) {
  1092.    Arg2->l.x = (long)(Arg2->l.x > Arg1->l.x) << bitshift; /* JCO 12/26/94 */
  1093.    Arg2->l.y = 0l;
  1094.    Arg1--;
  1095.    Arg2--;
  1096. }
  1097. #endif
  1098.  
  1099. void (*StkGT)(void) = dStkGT;
  1100.  
  1101. void dStkLTE(void) {
  1102.    Arg2->d.x = (double)(Arg2->d.x <= Arg1->d.x);
  1103.    Arg2->d.y = 0.0;
  1104.    Arg1--;
  1105.    Arg2--;
  1106. }
  1107.  
  1108. #ifndef XFRACT
  1109. void mStkLTE(void) {
  1110.    int comp;
  1111.  
  1112.    comp = MPcmp(Arg2->m.x, Arg1->m.x);
  1113.    Arg2->m.x = *fg2MP((long)(comp == -1 || comp == 0), 0);
  1114.    Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  1115.    Arg1--;
  1116.    Arg2--;
  1117. }
  1118.  
  1119. void lStkLTE(void) {
  1120.    Arg2->l.x = (long)(Arg2->l.x <= Arg1->l.x) << bitshift; /* JCO 12/26/94 */
  1121.    Arg2->l.y = 0l;
  1122.    Arg1--;
  1123.    Arg2--;
  1124. }
  1125. #endif
  1126.  
  1127. void (*StkLTE)(void) = dStkLTE;
  1128.  
  1129. void dStkGTE(void) {
  1130.    Arg2->d.x = (double)(Arg2->d.x >= Arg1->d.x);
  1131.    Arg2->d.y = 0.0;
  1132.    Arg1--;
  1133.    Arg2--;
  1134. }
  1135.  
  1136. #ifndef XFRACT
  1137. void mStkGTE(void) {
  1138.    int comp;
  1139.  
  1140.    comp = MPcmp(Arg2->m.x, Arg1->m.x);
  1141.    Arg2->m.x = *fg2MP((long)(comp == 1 || comp == 0), 0);
  1142.    Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  1143.    Arg1--;
  1144.    Arg2--;
  1145. }
  1146.  
  1147. void lStkGTE(void) {
  1148.    Arg2->l.x = (long)(Arg2->l.x >= Arg1->l.x) << bitshift; /* JCO 12/26/94 */
  1149.    Arg2->l.y = 0l;
  1150.    Arg1--;
  1151.    Arg2--;
  1152. }
  1153. #endif
  1154.  
  1155. void (*StkGTE)(void) = dStkGTE;
  1156.  
  1157. void dStkEQ(void) {
  1158.    Arg2->d.x = (double)(Arg2->d.x == Arg1->d.x);
  1159.    Arg2->d.y = 0.0;
  1160.    Arg1--;
  1161.    Arg2--;
  1162. }
  1163.  
  1164. #ifndef XFRACT
  1165. void mStkEQ(void) {
  1166.    int comp;
  1167.  
  1168.    comp = MPcmp(Arg2->m.x, Arg1->m.x);
  1169.    Arg2->m.x = *fg2MP((long)(comp == 0), 0);
  1170.    Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  1171.    Arg1--;
  1172.    Arg2--;
  1173. }
  1174.  
  1175. void lStkEQ(void) {
  1176.    Arg2->l.x = (long)(Arg2->l.x == Arg1->l.x) << bitshift; /* JCO 12/26/94 */
  1177.    Arg2->l.y = 0l;
  1178.    Arg1--;
  1179.    Arg2--;
  1180. }
  1181. #endif
  1182.  
  1183. void (*StkEQ)(void) = dStkEQ;
  1184.  
  1185. void dStkNE(void) {
  1186.    Arg2->d.x = (double)(Arg2->d.x != Arg1->d.x);
  1187.    Arg2->d.y = 0.0;
  1188.    Arg1--;
  1189.    Arg2--;
  1190. }
  1191.  
  1192. #ifndef XFRACT
  1193. void mStkNE(void) {
  1194.    int comp;
  1195.  
  1196.    comp = MPcmp(Arg2->m.x, Arg1->m.x);
  1197.    Arg2->m.x = *fg2MP((long)(comp != 0), 0);
  1198.    Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  1199.    Arg1--;
  1200.    Arg2--;
  1201. }
  1202.  
  1203. void lStkNE(void) {
  1204.    Arg2->l.x = (long)(Arg2->l.x != Arg1->l.x) << bitshift; /* JCO 12/26/94 */
  1205.    Arg2->l.y = 0l;
  1206.    Arg1--;
  1207.    Arg2--;
  1208. }
  1209. #endif
  1210.  
  1211. void (*StkNE)(void) = dStkNE;
  1212.  
  1213. void dStkOR(void) {
  1214.    Arg2->d.x = (double)(Arg2->d.x || Arg1->d.x);
  1215.    Arg2->d.y = 0.0;
  1216.    Arg1--;
  1217.    Arg2--;
  1218. }
  1219.  
  1220. #ifndef XFRACT
  1221. void mStkOR(void) {
  1222.    Arg2->m.x = *fg2MP((long)(Arg2->m.x.Mant || Arg1->m.x.Mant), 0);
  1223.    Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  1224.    Arg1--;
  1225.    Arg2--;
  1226. }
  1227.  
  1228. void lStkOR(void) {
  1229.    Arg2->l.x = (long)(Arg2->l.x || Arg1->l.x) << bitshift; /* JCO 12/26/94 */
  1230.    Arg2->l.y = 0l;
  1231.    Arg1--;
  1232.    Arg2--;
  1233. }
  1234. #endif
  1235.  
  1236. void (*StkOR)(void) = dStkOR;
  1237.  
  1238. void dStkAND(void) {
  1239.    Arg2->d.x = (double)(Arg2->d.x && Arg1->d.x);
  1240.    Arg2->d.y = 0.0;
  1241.    Arg1--;
  1242.    Arg2--;
  1243. }
  1244.  
  1245. #ifndef XFRACT
  1246. void mStkAND(void) {
  1247.    Arg2->m.x = *fg2MP((long)(Arg2->m.x.Mant && Arg1->m.x.Mant), 0);
  1248.    Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  1249.    Arg1--;
  1250.    Arg2--;
  1251. }
  1252.  
  1253. void lStkAND(void) {
  1254.    Arg2->l.x = (long)(Arg2->l.x && Arg1->l.x) << bitshift; /* JCO 12/26/94 */
  1255.    Arg2->l.y = 0l;
  1256.    Arg1--;
  1257.    Arg2--;
  1258. }
  1259. #endif
  1260.  
  1261. void (*StkAND)(void) = dStkAND;
  1262. void dStkLog(void) {
  1263.    FPUcplxlog(&Arg1->d, &Arg1->d);
  1264. }
  1265.  
  1266. #ifndef XFRACT
  1267. void mStkLog(void) {
  1268.    mStkFunct(dStkLog);   /* call lStk via dStk */
  1269. }
  1270.  
  1271. void lStkLog(void) {
  1272.    lStkFunct(dStkLog);
  1273. }
  1274. #endif
  1275.  
  1276. void (*StkLog)(void) = dStkLog;
  1277.  
  1278. void FPUcplxexp(_CMPLX *x, _CMPLX *z) {
  1279.    double e2x, siny, cosy;
  1280.  
  1281.    if(fpu == 387)
  1282.       FPUcplxexp387(x, z);
  1283.    else {
  1284.       e2x = exp(x->x);
  1285.       FPUsincos(&x->y, &siny, &cosy);
  1286.       z->x = e2x * cosy;
  1287.       z->y = e2x * siny;
  1288.    }
  1289. }
  1290.  
  1291.    void dStkExp(void) {
  1292.       FPUcplxexp(&Arg1->d, &Arg1->d);
  1293.    }
  1294.  
  1295. #ifndef XFRACT
  1296. void mStkExp(void) {
  1297.    mStkFunct(dStkExp);   /* call lStk via dStk */
  1298. }
  1299.  
  1300. void lStkExp(void) {
  1301.    lStkFunct(dStkExp);
  1302. }
  1303. #endif
  1304.  
  1305. void (*StkExp)(void) = dStkExp;
  1306.  
  1307. void dStkPwr(void) {
  1308.    Arg2->d = ComplexPower(Arg2->d, Arg1->d);
  1309.    Arg1--;
  1310.    Arg2--;
  1311. }
  1312.  
  1313. #ifndef XFRACT
  1314. void mStkPwr(void) {
  1315.    _CMPLX x, y;
  1316.  
  1317.    x = MPC2cmplx(Arg2->m);
  1318.    y = MPC2cmplx(Arg1->m);
  1319.    x = ComplexPower(x, y);
  1320.    Arg2->m = cmplx2MPC(x);
  1321.    Arg1--;
  1322.    Arg2--;
  1323. }
  1324.  
  1325. void lStkPwr(void) {
  1326.    _CMPLX x, y;
  1327.  
  1328.    x.x = (double)Arg2->l.x / fg;
  1329.    x.y = (double)Arg2->l.y / fg;
  1330.    y.x = (double)Arg1->l.x / fg;
  1331.    y.y = (double)Arg1->l.y / fg;
  1332.    x = ComplexPower(x, y);
  1333.    if(fabs(x.x) < fgLimit && fabs(x.y) < fgLimit) {
  1334.       Arg2->l.x = (long)(x.x * fg);
  1335.       Arg2->l.y = (long)(x.y * fg);
  1336.    }
  1337.    else
  1338.       overflow = 1;
  1339.    Arg1--;
  1340.    Arg2--;
  1341. }
  1342. #endif
  1343.  
  1344. void (*StkPwr)(void) = dStkPwr;
  1345.  
  1346. void EndInit(void) {
  1347.    LastInitOp = OpPtr;
  1348. }
  1349.  
  1350. #if (_MSC_VER >= 700)
  1351. #pragma code_seg ("parser1_text")     /* place following in an overlay */
  1352. #endif
  1353.  
  1354. struct ConstArg far *isconst(char *Str, int Len) {
  1355.    _CMPLX z;
  1356.    unsigned n, j;
  1357.  
  1358.    for(n = 0; n < vsp; n++) {
  1359.       if(v[n].len == Len) {
  1360.          if(!strnicmp(v[n].s, Str, Len))
  1361.          {
  1362.             if(n == 1)        /* The formula uses 'p1'. */
  1363.                uses_p1 = 1;
  1364.             if(n == 2)        /* The formula uses 'p2'. */
  1365.                uses_p2 = 1;
  1366.             if(n == 7)        /* The formula uses 'rand'. */
  1367.                RandomSeed();
  1368.             if(n == 8)        /* The formula uses 'p3'. */
  1369.                uses_p3 = 1;
  1370.             return(&v[n]);
  1371.          }
  1372.       }
  1373.    }
  1374.    v[vsp].s = Str;
  1375.    v[vsp].len = Len;
  1376.    v[vsp].a.d.x = v[vsp].a.d.y = 0.0;
  1377.    if(isdigit(Str[0])
  1378.        || (Str[0] == '-' && (isdigit(Str[1]) || Str[1] == '.'))
  1379.        || Str[0] == '.') {
  1380.       if(o[posp-1].f == StkNeg) {
  1381.          posp--;
  1382.          Str = Str - 1;
  1383.          InitN--;
  1384.          v[vsp].len++;
  1385.       }
  1386.       for(n = 1; isdigit(Str[n]) || Str[n] == '.'; n++);
  1387.       if(Str[n] == ',') {
  1388.          j = n + SkipWhiteSpace(&Str[n+1]) + 1;
  1389.          if(isdigit(Str[j]) 
  1390.              || (Str[j] == '-' && (isdigit(Str[j+1]) || Str[j+1] == '.'))
  1391.              || Str[j] == '.') {
  1392.             z.y = atof(&Str[j]);
  1393.             for(; isdigit(Str[j]) || Str[j] == '.' || Str[j] == '-'; j++);
  1394.             v[vsp].len = j;
  1395.          }
  1396.          else
  1397.             z.y = 0.0;
  1398.       }
  1399.       else
  1400.          z.y = 0.0;
  1401.       z.x = atof(Str);
  1402.       switch(MathType) {
  1403.       case D_MATH:
  1404.          v[vsp].a.d = z;
  1405.          break;
  1406. #ifndef XFRACT
  1407.       case M_MATH:
  1408.          v[vsp].a.m = cmplx2MPC(z);
  1409.          break;
  1410.       case L_MATH:
  1411.          v[vsp].a.l.x = (long)(z.x * fg);
  1412.          v[vsp].a.l.y = (long)(z.y * fg);
  1413.          break;
  1414. #endif
  1415.       }
  1416.       v[vsp].s = Str;
  1417.    }
  1418.    return(&v[vsp++]);
  1419. }
  1420.  
  1421.  
  1422. struct FNCT_LIST {
  1423.    char far *s;              /* TIW 03-31-91 added far */
  1424.    void (**ptr)(void);
  1425. };
  1426.  
  1427. /* TIW 03-30-91 START */
  1428. void (*StkTrig0)(void) = dStkSin;
  1429. void (*StkTrig1)(void) = dStkSqr;
  1430. void (*StkTrig2)(void) = dStkSinh;
  1431. void (*StkTrig3)(void) = dStkCosh;
  1432.  
  1433. char maxfn = 0;
  1434. /* TIW 03-30-91 STOP */
  1435.  
  1436. struct FNCT_LIST far FnctList[] = {   /* TIW 03-31-91 added far */
  1437.    s_sin,   &StkSin,
  1438.    s_sinh,  &StkSinh,
  1439.    s_cos,   &StkCos,
  1440.    s_cosh,  &StkCosh,
  1441.    s_sqr,   &StkSqr,
  1442.    s_log,   &StkLog,
  1443.    s_exp,   &StkExp,
  1444.    s_abs,   &StkAbs,
  1445.    s_conj,  &StkConj,
  1446.    s_real,  &StkReal,
  1447.    s_imag,  &StkImag,
  1448.    s_fn1,   &StkTrig0,   /* TIW 03-30-91 */
  1449.    s_fn2,   &StkTrig1,   /* TIW 03-30-91 */
  1450.    s_fn3,   &StkTrig2,   /* TIW 03-30-91 */
  1451.    s_fn4,   &StkTrig3,   /* TIW 03-30-91 */
  1452.    s_flip,  &StkFlip,    /* MCP 4-9-91 */
  1453.    s_tan,   &StkTan,     /* TIW 04-22-91 */
  1454.    s_tanh,  &StkTanh,    /* TIW 04-22-91 */
  1455.    s_cotan, &StkCoTan,   /* TIW 04-24-91 */
  1456.    s_cotanh,&StkCoTanh,  /* TIW 04-24-91 */
  1457.    s_cosxx, &StkCosXX,   /* PB  04-28-91 */
  1458.    s_srand, &StkSRand,   /* MCP 11-21-91 */
  1459.    s_asin,  &StkASin,    /* TIW 11-26-94 */
  1460.    s_asinh, &StkASinh,   /* TIW 11-26-94 */
  1461.    s_acos,  &StkACos,    /* TIW 11-26-94 */
  1462.    s_acosh, &StkACosh,   /* TIW 11-26-94 */
  1463.    s_atan,  &StkATan,    /* TIW 11-26-94 */
  1464.    s_atanh, &StkATanh,   /* TIW 11-26-94 */
  1465.    s_sqrt,  &StkSqrt,    /* TIW 11-26-94 */
  1466.    s_cabs,  &StkCAbs,    /* TIW 11-26-94 */
  1467. };
  1468.  
  1469. void NotAFnct(void) { }
  1470. void FnctNotFound(void) { }
  1471.  
  1472. /* determine if s names a function and if so which one */
  1473. /* TIW 04-22-91 */
  1474. whichfn(char *s, int len)
  1475. {
  1476.    int out;
  1477.    if(len != 3)
  1478.       out = 0;
  1479.    else if(strnicmp(s,"fn",2))
  1480.       out = 0;
  1481.    else
  1482.       out = atoi(s+2);
  1483.    if(out < 1 || out > 4)
  1484.       out = 0;
  1485.    return(out);
  1486. }
  1487.  
  1488. #ifndef XFRACT
  1489. void (far *isfunct(char *Str, int Len))(void)
  1490. #else
  1491. void (*isfunct(Str, Len))()
  1492. char *Str;
  1493. int Len;
  1494. #endif
  1495. {
  1496.    unsigned n;
  1497.    int functnum;    /* TIW 04-22-91 */
  1498.  
  1499.    n = SkipWhiteSpace(&Str[Len]);
  1500.    if(Str[Len+n] == '(') {
  1501.       for(n = 0; n < sizeof(FnctList) / sizeof(struct FNCT_LIST); n++) {
  1502.          if(far_strlen(FnctList[n].s) == Len) {        /* TIW 03-31-91 added far */
  1503.             if(!far_strnicmp(FnctList[n].s, Str, Len)) {  /* TIW 03-31-91 added far */
  1504.                /* count function variables */
  1505.                if((functnum = whichfn(Str, Len)) != 0)    /* TIW 04-22-91 */
  1506.                   if(functnum > maxfn)                  /* TIW 04-22-91 */
  1507.                      maxfn = (char)functnum;                  /* TIW 04-22-91 */
  1508.                return(*FnctList[n].ptr);
  1509.             }
  1510.          }
  1511.       }
  1512.       return(FnctNotFound);
  1513.    }
  1514.    return(NotAFnct);
  1515. }
  1516.  
  1517. void RecSortPrec(void) {
  1518.    int ThisOp = NextOp++;
  1519.  
  1520.    while(o[ThisOp].p > o[NextOp].p && NextOp < posp)
  1521.       RecSortPrec();
  1522.    f[OpPtr++] = o[ThisOp].f;
  1523. }
  1524.  
  1525. static char *Constants[] = {
  1526.    "pixel",        /* v[0] */
  1527.    "p1",           /* v[1] */
  1528.    "p2",           /* v[2] */
  1529.    "z",            /* v[3] */
  1530.    "LastSqr",      /* v[4] */
  1531.    "spare1",       /* v[5] */   /* use this slot for next constant */
  1532.    "spare2",       /* v[6] */   /* use this slot for next constant */
  1533.    "rand",         /* v[7] */
  1534.    "p3",           /* v[8] */
  1535. };
  1536.  
  1537. struct SYMETRY {
  1538.    char *s;
  1539.    int n;
  1540. } SymStr[] = {
  1541.    "NOSYM",         0,
  1542.    "XAXIS_NOPARM", -1,
  1543.    "XAXIS",         1,
  1544.    "YAXIS_NOPARM", -2,
  1545.    "YAXIS",         2,
  1546.    "XYAXIS_NOPARM",-3,
  1547.    "XYAXIS",        3,
  1548.    "ORIGIN_NOPARM",-4,
  1549.    "ORIGIN",        4,
  1550.    "PI_SYM_NOPARM",-5,
  1551.    "PI_SYM",        5,
  1552.    "XAXIS_NOIMAG", -6,
  1553.    "XAXIS_NOREAL",  6,
  1554.    "NOPLOT",       99,
  1555.    "", 0
  1556. };
  1557.  
  1558. int ParseStr(char *Str) {
  1559.    struct ConstArg far *c;
  1560.    int ModFlag = 999, Len, Equals = 0, Mod[20], mdstk = 0;
  1561.    int NewStatement;
  1562.    struct ERROR { int n, s; } far *e;
  1563.  
  1564.    SetRandom = Randomized = 0;
  1565.    e = (struct ERROR far *)farmemalloc(sizeof(struct ERROR) * 100L);
  1566.    /* PB 910417 changed "o" to be a temporary alloc, during ParseStr only */
  1567.    o = (struct PEND_OP far *)farmemalloc(sizeof(struct PEND_OP) * (long)MAX_OPS);
  1568.    if(!e || !o || !typespecific_workarea) {
  1569.       static char far msg[]={"Insufficient memory to run fractal type 'formula'"};
  1570.       stopmsg(0,msg);
  1571.       return(1);
  1572.    }
  1573.    switch(MathType) {
  1574.    case D_MATH:
  1575.       StkAdd = dStkAdd;
  1576.       StkSub = dStkSub;
  1577.       StkNeg = dStkNeg;
  1578.       StkMul = dStkMul;
  1579.       StkSin = dStkSin;
  1580.       StkSinh = dStkSinh;
  1581.       StkLT = dStkLT;
  1582.       StkLTE = dStkLTE;
  1583.       StkMod = dStkMod;
  1584.       StkSqr = dStkSqr;
  1585.       StkCos = dStkCos;
  1586.       StkCosh = dStkCosh;
  1587.       StkLog = dStkLog;
  1588.       StkExp = dStkExp;
  1589.       StkPwr = dStkPwr;
  1590.       StkDiv = dStkDiv;
  1591.       StkAbs = dStkAbs;
  1592.       StkReal = dStkReal;
  1593.       StkImag = dStkImag;
  1594.       StkConj = dStkConj;
  1595.       StkTrig0 = dtrig0;   /* TIW 03-30-91 */
  1596.       StkTrig1 = dtrig1;   /* TIW 03-30-91 */
  1597.       StkTrig2 = dtrig2;   /* TIW 03-30-91 */
  1598.       StkTrig3 = dtrig3;   /* TIW 03-30-91 */
  1599.       StkFlip = dStkFlip;
  1600.       StkTan = dStkTan;    /* TIW 04-22-91 */
  1601.       StkTanh = dStkTanh;  /* TIW 04-22-91 */
  1602.       StkCoTan = dStkCoTan;    /* TIW 04-24-91 */
  1603.       StkCoTanh = dStkCoTanh;  /* TIW 04-24-91 */
  1604.       StkCosXX = dStkCosXX;    /* PB  04-28-91 */
  1605.       StkGT  = dStkGT;         /* MCP 11-3-91 */
  1606.       StkGTE = dStkGTE;        /* MCP 11-3-91 */
  1607.       StkEQ  = dStkEQ;         /* MCP 11-3-91 */
  1608.       StkNE  = dStkNE;         /* MCP 11-3-91 */
  1609.       StkAND = dStkAND;        /* MCP 11-3-91 */
  1610.       StkOR  = dStkOR ;        /* MCP 11-3-91 */
  1611.       StkSRand = dStkSRand;    /* MCP 11-21-91 */
  1612.       StkASin = dStkASin;      /* TIW 11-25-94 */
  1613.       StkASinh = dStkASinh;    /* TIW 11-25-94 */
  1614.       StkACos = dStkACos;      /* TIW 11-25-94 */
  1615.       StkACosh = dStkACosh;    /* TIW 11-25-94 */
  1616.       StkATan = dStkATan;      /* TIW 11-25-94 */
  1617.       StkATanh = dStkATanh;    /* TIW 11-25-94 */
  1618.       StkCAbs = dStkCAbs;      /* TIW 11-25-94 */
  1619.       StkSqrt = dStkSqrt;      /* TIW 11-25-94 */
  1620.       StkZero = dStkZero;      /* JCO 12-31-94 */
  1621.       break;
  1622. #ifndef XFRACT
  1623.    case M_MATH:
  1624.       StkAdd = mStkAdd;
  1625.       StkSub = mStkSub;
  1626.       StkNeg = mStkNeg;
  1627.       StkMul = mStkMul;
  1628.       StkSin = mStkSin;
  1629.       StkSinh = mStkSinh;
  1630.       StkLT = mStkLT;
  1631.       StkLTE = mStkLTE;
  1632.       StkMod = mStkMod;
  1633.       StkSqr = mStkSqr;
  1634.       StkCos = mStkCos;
  1635.       StkCosh = mStkCosh;
  1636.       StkLog = mStkLog;
  1637.       StkExp = mStkExp;
  1638.       StkPwr = mStkPwr;
  1639.       StkDiv = mStkDiv;
  1640.       StkAbs = mStkAbs;
  1641.       StkReal = mStkReal;
  1642.       StkImag = mStkImag;
  1643.       StkConj = mStkConj;
  1644.       StkTrig0 = mtrig0;  /* TIW 03-30-91 */
  1645.       StkTrig1 = mtrig1;  /* TIW 03-30-91 */
  1646.       StkTrig2 = mtrig2;  /* TIW 03-30-91 */
  1647.       StkTrig3 = mtrig3;  /* TIW 03-30-91 */
  1648.       StkFlip = mStkFlip;
  1649.       StkTan  = mStkTan;  /* TIW 04-22-91 */
  1650.       StkTanh  = mStkTanh;/* TIW 04-22-91 */
  1651.       StkCoTan  = mStkCoTan;  /* TIW 04-24-91 */
  1652.       StkCoTanh  = mStkCoTanh;/* TIW 04-24-91 */
  1653.       StkCosXX = mStkCosXX;   /* PB  04-28-91 */
  1654.       StkGT  = mStkGT;         /* MCP 11-3-91 */
  1655.       StkGTE = mStkGTE;        /* MCP 11-3-91 */
  1656.       StkEQ  = mStkEQ;         /* MCP 11-3-91 */
  1657.       StkNE  = mStkNE;         /* MCP 11-3-91 */
  1658.       StkAND = mStkAND;        /* MCP 11-3-91 */
  1659.       StkOR  = mStkOR ;        /* MCP 11-3-91 */
  1660.       StkSRand = mStkSRand;    /* MCP 11-21-91 */
  1661.       StkASin = mStkASin;      /* TIW 11-25-94 */
  1662.       StkACos = mStkACos;      /* TIW 11-25-94 */
  1663.       StkACosh = mStkACosh;    /* TIW 11-25-94 */
  1664.       StkATan = mStkATan;      /* TIW 11-25-94 */
  1665.       StkATanh = mStkATanh;    /* TIW 11-25-94 */
  1666.       StkCAbs = mStkCAbs;      /* TIW 11-25-94 */
  1667.       StkSqrt = mStkSqrt;      /* TIW 11-25-94 */
  1668.       StkZero = mStkZero;      /* JCO 12-31-94 */
  1669.       break;
  1670.    case L_MATH:
  1671.       Delta16 = bitshift - 16;
  1672.       ShiftBack = 32 - bitshift; /* TW 06-18-90 */
  1673.       StkAdd = lStkAdd;
  1674.       StkSub = lStkSub;
  1675.       StkNeg = lStkNeg;
  1676.       StkMul = lStkMul;
  1677.       StkSin = lStkSin;
  1678.       StkSinh = lStkSinh;
  1679.       StkLT = lStkLT;
  1680.       StkLTE = lStkLTE;
  1681.       StkMod = lStkMod;
  1682.       StkSqr = lStkSqr;
  1683.       StkCos = lStkCos;
  1684.       StkCosh = lStkCosh;
  1685.       StkLog = lStkLog;
  1686.       StkExp = lStkExp;
  1687.       StkPwr = lStkPwr;
  1688.       StkDiv = lStkDiv;
  1689.       StkAbs = lStkAbs;
  1690.       StkReal = lStkReal;
  1691.       StkImag = lStkImag;
  1692.       StkConj = lStkConj;
  1693.       StkTrig0 = ltrig0;   /* TIW 03-30-91 */
  1694.       StkTrig1 = ltrig1;   /* TIW 03-30-91 */
  1695.       StkTrig2 = ltrig2;   /* TIW 03-30-91 */
  1696.       StkTrig3 = ltrig3;   /* TIW 03-30-91 */
  1697.       StkFlip = lStkFlip;
  1698.       StkTan  = lStkTan;   /* TIW 04-22-91 */
  1699.       StkTanh  = lStkTanh; /* TIW 04-22-91 */
  1700.       StkCoTan  = lStkCoTan;   /* TIW 04-24-91 */
  1701.       StkCoTanh  = lStkCoTanh; /* TIW 04-24-91 */
  1702.       StkCosXX = lStkCosXX;    /* PB  04-28-91 */
  1703.       StkGT  = lStkGT;         /* MCP 11-3-91 */
  1704.       StkGTE = lStkGTE;        /* MCP 11-3-91 */
  1705.       StkEQ  = lStkEQ;         /* MCP 11-3-91 */
  1706.       StkNE  = lStkNE;         /* MCP 11-3-91 */
  1707.       StkAND = lStkAND;        /* MCP 11-3-91 */
  1708.       StkOR  = lStkOR ;        /* MCP 11-3-91 */
  1709.       StkSRand = lStkSRand;    /* MCP 11-21-91 */
  1710.       StkASin = lStkASin;      /* TIW 11-25-94 */
  1711.       StkACos = lStkACos;      /* TIW 11-25-94 */
  1712.       StkACosh = lStkACosh;    /* TIW 11-25-94 */
  1713.       StkATan = lStkATan;      /* TIW 11-25-94 */
  1714.       StkATanh = lStkATanh;    /* TIW 11-25-94 */
  1715.       StkCAbs = lStkCAbs;      /* TIW 11-25-94 */
  1716.       StkSqrt = lStkSqrt;      /* TIW 11-25-94 */
  1717.       StkZero = lStkZero;      /* JCO 12-31-94 */
  1718.       break;
  1719. #endif
  1720.    }
  1721.    maxfn = 0;   /* TIW 03-30-91 */
  1722.    for(vsp = 0; vsp < sizeof(Constants) / sizeof(char*); vsp++) {
  1723.       v[vsp].s = Constants[vsp];
  1724.       v[vsp].len = strlen(Constants[vsp]);
  1725.    }
  1726.  
  1727.    /* 
  1728.    v[6].a.d.x = v[6].a.d.y = 0.0;
  1729.    v[7].a = v[6].a;
  1730.    */
  1731.    v[7].a.d.x = v[7].a.d.y = 0.0;
  1732.    
  1733.    switch(MathType) {
  1734.    case D_MATH:
  1735.       v[1].a.d.x = param[0];
  1736.       v[1].a.d.y = param[1];
  1737.       v[2].a.d.x = param[2];
  1738.       v[2].a.d.y = param[3];
  1739.       v[8].a.d.x = param[4];
  1740.       v[8].a.d.y = param[5];
  1741.       break;
  1742. #ifndef XFRACT
  1743.    case M_MATH:
  1744.       v[1].a.m.x = *d2MP(param[0]);
  1745.       v[1].a.m.y = *d2MP(param[1]);
  1746.       v[2].a.m.x = *d2MP(param[2]);
  1747.       v[2].a.m.y = *d2MP(param[3]);
  1748.       v[8].a.m.x = *d2MP(param[4]);
  1749.       v[8].a.m.y = *d2MP(param[5]);
  1750.       break;
  1751.    case L_MATH:
  1752.       v[1].a.l.x = (long)(param[0] * fg);
  1753.       v[1].a.l.y = (long)(param[1] * fg);
  1754.       v[2].a.l.x = (long)(param[2] * fg);
  1755.       v[2].a.l.y = (long)(param[3] * fg);
  1756.       v[8].a.l.x = (long)(param[4] * fg);
  1757.       v[8].a.l.y = (long)(param[5] * fg);
  1758.       break;
  1759. #endif
  1760.    }
  1761.  
  1762.    LastInitOp = ErrPtr = paren = OpPtr = LodPtr = StoPtr = posp = 0;
  1763.    NewStatement = 1;
  1764.    SyntaxErr = -1;
  1765.    ExpectingArg = 1;
  1766.    for(n = 0; Str[n]; n++) {
  1767.       if(!Str[n])
  1768.          break;
  1769.       InitN = n;
  1770.       switch(Str[n]) {
  1771.       case ' ':
  1772.       case '\t':
  1773.       case '\r':
  1774.       case '\n':
  1775.          break;
  1776.       case '(':
  1777.          paren++;
  1778.          if(!ExpectingArg)
  1779.             SyntaxErr = 1;
  1780.          break;
  1781.       case ')':
  1782.          if(paren)
  1783.             paren--;
  1784.          else
  1785.             SyntaxErr = 2;
  1786.          if(ExpectingArg) {
  1787.             e[ErrPtr].n = InitN;
  1788.             e[ErrPtr++].s = 0;
  1789.          }
  1790.          break;
  1791.       case '|':
  1792.          if(Str[n+1] == '|') {
  1793.             if(ExpectingArg)
  1794.                SyntaxErr = 0;
  1795.             ExpectingArg = 1;
  1796.             n++;
  1797.             o[posp].f = StkOR;
  1798.             o[posp++].p = 7 - (paren + Equals)*15;
  1799.          }
  1800.          else if(ModFlag == paren-1) {
  1801.             if(ExpectingArg)
  1802.                SyntaxErr = 0;
  1803.             paren--;
  1804.             ModFlag = Mod[--mdstk];
  1805.          }
  1806.          else {
  1807.             if(!ExpectingArg)
  1808.                SyntaxErr = 1;
  1809.             Mod[mdstk++] = ModFlag;
  1810.             o[posp].f = StkMod;
  1811.             o[posp++].p = 2 - (paren + Equals)*15;
  1812.             ModFlag = paren++;
  1813.          }
  1814.          break;
  1815.       case ',':
  1816.       case ';':
  1817.          if(paren) {
  1818.             e[ErrPtr].n = InitN;
  1819.             e[ErrPtr++].s = 3;
  1820.          }
  1821.          if(!ExpectingArg) {
  1822.             NewStatement = 1;
  1823.             ExpectingArg = 1;
  1824.             o[posp].f = (void(far*)(void))0;
  1825.             o[posp++].p = 15;
  1826.             o[posp].f = StkClr;
  1827.             o[posp++].p = -30000;
  1828.             Equals = paren = 0;
  1829.          }
  1830.          else if(!NewStatement)
  1831.             SyntaxErr = 0;
  1832.          break;
  1833.       case ':':
  1834.          if(paren) {
  1835.             e[ErrPtr].n = InitN;
  1836.             e[ErrPtr++].s = 3;
  1837.          }
  1838.          if(ExpectingArg)
  1839.             SyntaxErr = 0;
  1840.          else
  1841.             ExpectingArg = 1;
  1842.          o[posp].f = (void(far*)(void))0;
  1843.          o[posp++].p = 15;
  1844.          o[posp].f = EndInit;
  1845.          o[posp++].p = -30000;
  1846.          Equals = paren = 0;
  1847.          LastInitOp = 10000;
  1848.          NewStatement = 1;
  1849.          break;
  1850.       case '+':
  1851.          if(ExpectingArg)
  1852.             SyntaxErr = 0;
  1853.          ExpectingArg = 1;
  1854.          o[posp].f = StkAdd;
  1855.          o[posp++].p = 4 - (paren + Equals)*15;
  1856.          break;
  1857.       case '-':
  1858.          if(ExpectingArg) {
  1859.             o[posp].f = StkNeg;
  1860.             o[posp++].p = 2 - (paren + Equals)*15;
  1861.          }
  1862.          else {
  1863.             o[posp].f = StkSub;
  1864.             o[posp++].p = 4 - (paren + Equals)*15;
  1865.             ExpectingArg = 1;
  1866.          }
  1867.          break;
  1868.       case '&':
  1869.          if(ExpectingArg)
  1870.             SyntaxErr = 0;
  1871.          ExpectingArg = 1;
  1872.          if(Str[n+1] == '&') {
  1873.             n++;
  1874.             o[posp].f = StkAND;
  1875.             o[posp++].p = 7 - (paren + Equals)*15;
  1876.          }
  1877.          else
  1878.             SyntaxErr = 4;
  1879.          break;
  1880.       case '!':
  1881.          if(Str[n+1] == '=') {
  1882.             if(ExpectingArg)
  1883.                SyntaxErr = 0;
  1884.             ExpectingArg = 1;
  1885.             n++;
  1886.             o[posp].f = StkNE;
  1887.             o[posp++].p = 6 - (paren + Equals)*15;
  1888.          }
  1889.          else
  1890.             SyntaxErr = 4;
  1891.          break;
  1892.       case '<':
  1893.          if(ExpectingArg)
  1894.             SyntaxErr = 0;
  1895.          ExpectingArg = 1;
  1896.          if(Str[n+1] == '=') {
  1897.             n++;
  1898.             o[posp].f = StkLTE;
  1899.          }
  1900.          else
  1901.             o[posp].f = StkLT;
  1902.          o[posp++].p = 6 - (paren + Equals)*15;
  1903.          break;
  1904.       case '>':
  1905.          if(ExpectingArg)
  1906.             SyntaxErr = 0;
  1907.          ExpectingArg = 1;
  1908.          if(Str[n+1] == '=') {
  1909.             n++;
  1910.             o[posp].f = StkGTE;
  1911.          }
  1912.          else
  1913.             o[posp].f = StkGT;
  1914.          o[posp++].p = 6 - (paren + Equals)*15;
  1915.          break;
  1916.       case '*':
  1917.          if(ExpectingArg)
  1918.             SyntaxErr = 0;
  1919.          ExpectingArg = 1;
  1920.          o[posp].f = StkMul;
  1921.          o[posp++].p = 3 - (paren + Equals)*15;
  1922.          break;
  1923.       case '/':
  1924.          if(ExpectingArg)
  1925.             SyntaxErr = 0;
  1926.          ExpectingArg = 1;
  1927.          o[posp].f = StkDiv;
  1928.          o[posp++].p = 3 - (paren + Equals)*15;
  1929.          break;
  1930.       case '^':
  1931.          if(ExpectingArg)
  1932.             SyntaxErr = 0;
  1933.          ExpectingArg = 1;
  1934.          o[posp].f = StkPwr;
  1935.          o[posp++].p = 2 - (paren + Equals)*15;
  1936.          break;
  1937.       case '=':
  1938.          if(ExpectingArg)
  1939.             SyntaxErr = 0;
  1940.          ExpectingArg = 1;
  1941.          if(Str[n+1] == '=') {
  1942.             n++;
  1943.             o[posp].f = StkEQ;
  1944.             o[posp++].p = 6 - (paren + Equals)*15;
  1945.          }
  1946.          else
  1947.          {
  1948.             o[posp-1].f = StkSto;
  1949.             o[posp-1].p = 5 - (paren + Equals)*15;
  1950.             Store[StoPtr++] = Load[--LodPtr];
  1951.             Equals++;
  1952.          }
  1953.          break;
  1954.       default:
  1955.          if(isalnum(Str[n]) || Str[n] == '.') {
  1956.             while(isalnum(Str[n+1]) || Str[n+1] == '.')
  1957.                n++;
  1958.             if(!ExpectingArg) {
  1959.                SyntaxErr = 1;
  1960.             }
  1961.             NewStatement = ExpectingArg = 0;
  1962.             Len = (n+1)-InitN;
  1963.             o[posp].f = isfunct(&Str[InitN], Len);
  1964.             if(o[posp].f != NotAFnct) {
  1965.                if(o[posp].f == FnctNotFound) {
  1966.                   e[ErrPtr].n = InitN;
  1967.                   e[ErrPtr++].s = 5;
  1968.                }
  1969.                else
  1970.                   o[posp++].p = 1 - (paren + Equals)*15;
  1971.                ExpectingArg = 1;
  1972.             }
  1973.             else {
  1974.                c = isconst(&Str[InitN], Len);
  1975.                Load[LodPtr++] = &(c->a);
  1976.                o[posp].f = StkLod;
  1977.                o[posp++].p = 1 - (paren + Equals)*15;
  1978.                n = InitN + c->len - 1;
  1979.                if(vsp >= MAX_ARGS-1) { /* PB 910417 safety test */
  1980.                   e[ErrPtr].n = InitN;
  1981.                   e[ErrPtr++].s = 7;
  1982.                   break;
  1983.                }
  1984.             }
  1985.          }
  1986.          else {
  1987.             if(ExpectingArg)
  1988.                SyntaxErr = 0;
  1989.             ExpectingArg = 1;
  1990.             e[ErrPtr].n = InitN;
  1991.             e[ErrPtr++].s = 4;
  1992.          }
  1993.          break;
  1994.       }
  1995.       if(SyntaxErr >= 0) {
  1996.          e[ErrPtr].n = InitN;
  1997.          e[ErrPtr++].s = SyntaxErr;
  1998.          SyntaxErr = -1;
  1999.       }
  2000.       if(posp >= MAX_OPS-1) { /* PB 901103 added safety test here */
  2001.          e[ErrPtr].n = InitN;
  2002.          e[ErrPtr++].s = 7;
  2003.          break;
  2004.       }
  2005.       if(ErrPtr > 50)         /* PB 910417 safety test */
  2006.          break;
  2007.    }
  2008.  
  2009.    o[posp].f = (void(far*)(void))0;
  2010.    o[posp++].p = 16;
  2011.    if(paren > 0) {
  2012.       e[ErrPtr].n = n;
  2013.       e[ErrPtr++].s = 3;
  2014.    }
  2015.    if (ErrPtr) {
  2016.       int i, j, k, m;
  2017.       char msgbuf[700];  /* PB replaced printf loop by build msgbuf & stopmsg */
  2018.       /* stopmsg defined to have max 9 lines, show at most first 3 errors */
  2019.       msgbuf[0] = 0;
  2020.       for(n = 0; n < ErrPtr && n < 3; n++) {
  2021.          if (n)
  2022.             strcat(msgbuf,"\n");
  2023. #ifndef XFRACT
  2024.          sprintf(&msgbuf[strlen(msgbuf)], "Error(%d):  %Fs\n  ", e[n].s, /*TIW 03-31-91 added %Fs*/
  2025.             ErrStrings[e[n].s]);
  2026. #else
  2027.          sprintf(&msgbuf[strlen(msgbuf)], "Error(%d):  %s\n  ", e[n].s,
  2028.             ErrStrings[e[n].s]);
  2029. #endif
  2030.          j = 24;
  2031.          if ((i = e[n].n - j) < 0) {
  2032.             j = e[n].n;
  2033.             i = 0;
  2034.          }
  2035.          else {
  2036.             strcat(msgbuf,"...");
  2037.             j += 3;
  2038.          }
  2039.          k = strlen(msgbuf);
  2040.          m = i + 66;
  2041.          while (i < m && Str[i]) {
  2042.             if ((msgbuf[k] = Str[i]) == '\n' || msgbuf[k] == '\t')
  2043.                msgbuf[k] = ' ';
  2044.             ++i;
  2045.             ++k;
  2046.          }
  2047.          if (Str[i]) {
  2048.             msgbuf[k++] = '.';
  2049.             msgbuf[k++] = '.';
  2050.             msgbuf[k++] = '.';
  2051.          }
  2052.          msgbuf[k++] = '\n';
  2053.          while (--j >= -2)
  2054.             msgbuf[k++] = ' ';
  2055.          msgbuf[k++] = '^';
  2056.          msgbuf[k] = 0;
  2057.       }
  2058.       stopmsg(8,msgbuf);
  2059.    }
  2060.    if(!ErrPtr) {
  2061.       NextOp = 0;
  2062.       LastOp = posp;
  2063.       while(NextOp < posp) {
  2064.          if(o[NextOp].f)
  2065.             RecSortPrec();
  2066.          else {
  2067.             NextOp++;
  2068.             LastOp--;
  2069.          }
  2070.       }
  2071.    }
  2072.    else
  2073.       posp = 0;
  2074.    farmemfree(o);
  2075.    farmemfree(e);
  2076.    /* PB 910417 free all arrays if error */
  2077.    if (ErrPtr)
  2078.       free_workarea();
  2079.    return(ErrPtr);
  2080. }
  2081.  
  2082. #if (_MSC_VER >= 700)
  2083. #pragma code_seg ()       /* back to normal segment */
  2084. #endif
  2085.  
  2086. int Formula(void) {
  2087.    if(FormName[0] == 0 || overflow) return(1);
  2088.  
  2089.    LodPtr = InitLodPtr;
  2090.    StoPtr = InitStoPtr;
  2091.    OpPtr = InitOpPtr;
  2092.  
  2093.    /* Set the random number, MCP 11-21-91 */
  2094.    if(SetRandom || Randomized)
  2095.    {
  2096.       switch(MathType)
  2097.       {
  2098.       case D_MATH:
  2099.          dRandom();
  2100.          break;
  2101. #ifndef XFRACT
  2102.       case L_MATH:
  2103.          lRandom();
  2104.          break;
  2105.       case M_MATH:
  2106.          mRandom();
  2107. #endif
  2108.       }
  2109.    }
  2110.  
  2111.    Arg1 = &s[0];
  2112.    Arg2 = Arg1-1;
  2113.    while(OpPtr < (int)LastOp) {
  2114.       f[OpPtr++]();
  2115. #ifdef WATCH_MP
  2116.       x1 = *MP2d(Arg1->m.x);
  2117.       y1 = *MP2d(Arg1->m.y);
  2118.       x2 = *MP2d(Arg2->m.x);
  2119.       y2 = *MP2d(Arg2->m.y);
  2120. #endif
  2121.    }
  2122.  
  2123.    switch(MathType) {
  2124.    case D_MATH:
  2125.       old = new = v[3].a.d;
  2126.       return(Arg1->d.x == 0.0);
  2127. #ifndef XFRACT
  2128.    case M_MATH:
  2129.       old = new = MPC2cmplx(v[3].a.m);
  2130.       return(Arg1->m.x.Exp == 0 && Arg1->m.x.Mant == 0);
  2131.    case L_MATH:
  2132.       lold = lnew = v[3].a.l;
  2133.       if(overflow)
  2134.          return(1);
  2135.       return(Arg1->l.x == 0L);
  2136. #endif
  2137.    }
  2138.    return(1);
  2139. }
  2140.  
  2141. int form_per_pixel(void) {
  2142.    if (FormName[0] == 0) return(1);
  2143.    overflow = LodPtr = StoPtr = OpPtr = 0;
  2144.    Arg1 = &s[0];
  2145.    Arg2 = Arg1;
  2146.    Arg2--;
  2147.    /* TW started additions for inversion support here 4/17/94 */
  2148.    {
  2149.       if(invert)
  2150.       {
  2151.          invertz2(&old);
  2152.          switch(MathType)
  2153.          {
  2154.          case D_MATH:
  2155.             v[0].a.d.x = old.x;
  2156.             v[0].a.d.y = old.y;
  2157.             break;
  2158. #ifndef XFRACT
  2159.          case M_MATH:
  2160.             v[0].a.m.x = *d2MP(old.x);
  2161.             v[0].a.m.y = *d2MP(old.y);
  2162.             break;
  2163.          case L_MATH:
  2164.             /* watch out for overflow */
  2165.             if(sqr(old.x)+sqr(old.y) >= 127)
  2166.             {
  2167.            old.x = 8;  /* value to bail out in one iteration */
  2168.            old.y = 8;
  2169.             }
  2170.             /* convert to fudged longs */
  2171.             v[0].a.l.x = (long)(old.x*fg);
  2172.             v[0].a.l.y = (long)(old.y*fg);
  2173.             break;
  2174. #endif
  2175.          }
  2176.       }
  2177.       else
  2178.          /* TW end of inversion support changes here 4/17/94 */
  2179.          switch(MathType)
  2180.          {
  2181.          case D_MATH:
  2182.             v[0].a.d.x = dx0[col]+dShiftx;
  2183.             v[0].a.d.y = dy0[row]+dShifty;
  2184.             break;
  2185. #ifndef XFRACT
  2186.          case M_MATH:
  2187.             v[0].a.m.x = *d2MP(dx0[col]+dShiftx);
  2188.             v[0].a.m.y = *d2MP(dy0[row]+dShifty);
  2189.             break;
  2190.          case L_MATH:
  2191.             v[0].a.l.x = lx0[col]+lShiftx;
  2192.             v[0].a.l.y = ly0[row]+lShifty;
  2193.             break;
  2194. #endif
  2195.          }
  2196.    }
  2197.  
  2198.    if(LastInitOp)
  2199.       LastInitOp = LastOp;
  2200.    while(OpPtr < LastInitOp)
  2201.       f[OpPtr++]();
  2202.  
  2203.    InitLodPtr = LodPtr;
  2204.    InitStoPtr = StoPtr;
  2205.    InitOpPtr = OpPtr;
  2206.    /* Set old variable for orbits TIW 12-18-93 */
  2207.    switch(MathType) {
  2208.    case D_MATH:
  2209.       old = v[3].a.d;
  2210.       break;
  2211. #ifndef XFRACT
  2212.    case M_MATH:
  2213.       old = MPC2cmplx(v[3].a.m);
  2214.       break;
  2215.    case L_MATH:
  2216.       lold = v[3].a.l;
  2217.       break; 
  2218. #endif
  2219.    }
  2220.  
  2221.    if(overflow)
  2222.       return(0);
  2223.    else
  2224.       return(1);
  2225. }
  2226.  
  2227. char *FormStr;
  2228. #if (_MSC_VER >= 700)
  2229. #pragma code_seg ("parser1_text")     /* place following in an overlay */
  2230. #endif
  2231.  
  2232. char *FindFormula(char *Str) {
  2233.    char *FormulaStr = (char *)0;
  2234.    char StrBuff[201];      /* PB, to match a safety fix in parser */
  2235.    /* MCP, changed to an automatic variable */
  2236.    char fullfilename[100]; /* BDT Full file name */
  2237.    unsigned Done;
  2238.    int c;
  2239.    FILE *File;
  2240.  
  2241.    findpath(FormFileName, fullfilename);  /* BDT get full path name */
  2242.  
  2243.    symmetry = 0;
  2244.    if((File = fopen(fullfilename, "rt")) != NULL) { /* BDT use variable files */
  2245.       while(StrBuff[0]=0,/* TIW 04-22-91 */ fscanf(File, "%200[^ \n\t({]", StrBuff) != EOF) {
  2246.          if(!stricmp(StrBuff, Str) || !Str[0]) {
  2247.             while((c = getc(File)) != EOF) {
  2248.                if(c == '(') {
  2249.                   StrBuff[0]=0; /* TIW 04-22-91 */
  2250.                   fscanf(File, "%200[^)]", StrBuff);
  2251.                   despace(StrBuff); /* squeeze out spaces */
  2252.                   for(n = 0; SymStr[n].s[0]; n++) {
  2253.                      if(!stricmp(SymStr[n].s, StrBuff)) {
  2254.                         symmetry = SymStr[n].n;
  2255.                         break;
  2256.                      }
  2257.                   }
  2258.                   if(!SymStr[n].s[0]) {
  2259.                      sprintf(fullfilename,"Undefined symmetry:\n  %.76s",
  2260.                         StrBuff);
  2261.                      stopmsg(0,fullfilename); /* PB printf -> stopmsg */
  2262.                      FormulaStr = (char *)0;  /* PB 910511 */
  2263. Exit:
  2264.                      fclose(File);
  2265.                      return(FormulaStr);
  2266.                   }
  2267.                }
  2268.                else if(c == '{')
  2269.                   break;
  2270.             }
  2271.  
  2272.             /* MCP 4-9-91, Strip the comments inside the formula.  Might
  2273.                            as well allow unlimited formula lengths while
  2274.                            we're at it.
  2275.             */
  2276.  
  2277.             FormulaStr = (char *)boxx;
  2278.             n = Done = 0;
  2279.             while(!Done) {
  2280.                switch(c = getc(File)) {
  2281.                   static char far msg[]={"Unexpected EOF:  missing a '}'"};
  2282.                case EOF:
  2283. UnexpectedEOF:
  2284.                   stopmsg(0, msg);
  2285.                   FormulaStr = (char *)0;
  2286.                   goto Exit;
  2287.                case '}':
  2288.                   FormulaStr[n++] = 0;
  2289.                   Done = 1;
  2290.                   break;
  2291.                case ';':
  2292.                   while((c = getc(File)) != '\n') {
  2293.                      if(c == EOF)
  2294.                         goto UnexpectedEOF;
  2295.                   }
  2296.                   FormulaStr[n++] = ',';
  2297.                   break;
  2298.                case ' ':                     /* Also strip out the
  2299.                                                    white spaces */
  2300.                                     
  2301.                case '\t':
  2302.                   break;
  2303.                case '\n':
  2304.                   FormulaStr[n++] = ',';
  2305.                   break;
  2306.                default:
  2307.                   FormulaStr[n++] = (char)c;
  2308.                }
  2309.                if (n >= 8192) { /* PB 4-9-91, added safety test */
  2310.                   static char far msg[]={"Definition too large, missing a '}'?"};
  2311.                   stopmsg(0, msg);
  2312.                   FormulaStr = (char *)0;
  2313.                   goto Exit;
  2314.                }
  2315.             }
  2316.             goto Exit;
  2317.          }
  2318.          else /* TW 5-31-94 add comments support */
  2319.          {
  2320.             c = getc(File);
  2321.             if( c != ';' && c != EOF)
  2322.                ungetc(c,File);
  2323.             else if(c == EOF) 
  2324.                goto UnexpectedEOF;
  2325.             else /* skip comment */
  2326.                while((c = getc(File)) != '\n') {
  2327.                   if(c == EOF)
  2328.                      goto UnexpectedEOF;
  2329.                }
  2330.          }   
  2331.         
  2332.          StrBuff[0]=0;  /* TIW 04-22-91 */
  2333.          fscanf(File, "%200[ \n\t({]", StrBuff);
  2334.          if(StrBuff[strcspn(StrBuff, "{")]) {
  2335.             do /* TW 5-31-94 add EOF loop exit */
  2336.                fscanf(File, "%200[^}]", StrBuff);
  2337.             while((c=getc(File)) != '}' && c != EOF);
  2338.          }
  2339.       }
  2340. #if 0 /* error message now in find_file_item in MISCRES.C TW 5-31-94 */
  2341.       sprintf(fullfilename, "Formula \"%s\" not found", Str);
  2342.       stopmsg(0,fullfilename);      /* PB printf -> stopmsg */
  2343. #endif
  2344.       FormulaStr = (char *)0;       /* PB 910511 */
  2345.       goto Exit;
  2346.    }
  2347.    sprintf(fullfilename, "Unable to open %s", FormFileName);
  2348.    stopmsg(0,fullfilename);      /* PB printf -> stopmsg */
  2349.    return((char *)0);            /* PB 910511 */
  2350. }
  2351.  
  2352. int BadFormula(void) {
  2353.    /*  moved from Parsera.Asm by CAE  12 July 1993  */
  2354.  
  2355.    /*  this is called when a formula is bad, instead of calling  */
  2356.    /*     the normal functions which will produce undefined results  */
  2357.    return 1;
  2358. }
  2359.  
  2360. int RunForm(char *Name) {  /*  returns 1 if an error occurred  */
  2361.    /*  CAE changed fn 12 July 1993 to fix problem when formula not found  */
  2362.  
  2363.    /*  first set the pointers so they point to a fn which always returns 1  */
  2364.    curfractalspecific->per_pixel = BadFormula;
  2365.    curfractalspecific->orbitcalc = BadFormula;
  2366.  
  2367.    if (FormName[0] == 0 ){
  2368.       return 1;  /*  and don't reset the pointers  */
  2369.    }
  2370.  
  2371.    parser_allocate();  /*  ParseStr() will test if this alloc worked  */
  2372.  
  2373.    /* TW 5-31-94 add search for FRM files in directory */
  2374.    find_file_item(FormFileName,Name,NULL);
  2375.  
  2376.    if((FormStr = FindFormula(Name)) != NULL ){
  2377.       /*  formula was found  */
  2378.       if (ParseStr(FormStr)){
  2379.          /*  parse failed, don't change fn pointers  */
  2380.          return 1;
  2381.       }
  2382.       else {
  2383.          /*  parse succeeded so set the pointers back to good functions  */
  2384.          curfractalspecific->per_pixel = form_per_pixel;
  2385.          curfractalspecific->orbitcalc = Formula;
  2386.          return 0;
  2387.       }
  2388.    }
  2389.    else {
  2390.       /*  formula not found, leave pointers set to BadFormula  */
  2391.       return 1;                    /* PB, msg moved to FindFormula */
  2392.    }
  2393. }
  2394.  
  2395. int fpFormulaSetup(void) {
  2396. #ifndef XFRACT
  2397.    int RunFormRes;        /* CAE fp */
  2398.  
  2399.    if (fpu > 0) {
  2400.       MathType = D_MATH;
  2401.       /* CAE changed below for fp */
  2402.       RunFormRes = !RunForm(FormName); /* RunForm() returns 1 for failure */
  2403.       if (RunFormRes && fpu >=387 && debugflag != 90)  /* && !invert  */
  2404.          return CvtStk(); /* run fast assembler code in parsera.asm */
  2405.       return RunFormRes;
  2406.    }
  2407.    else {
  2408.       MathType = M_MATH;
  2409.       return !RunForm(FormName);
  2410.    }
  2411. #else
  2412.    MathType = D_MATH;
  2413.    return(!RunForm(FormName));
  2414. #endif
  2415. }
  2416.  
  2417. int intFormulaSetup(void) {
  2418. #ifdef XFRACT
  2419.       printf("intFormulaSetup called!!!\n");
  2420.       exit(-1);
  2421. #endif
  2422.       MathType = L_MATH;
  2423.       fg = (double)(1L << bitshift);
  2424.       fgLimit = (double)0x7fffffffL / fg;
  2425.       ShiftBack = 32 - bitshift;
  2426.       return(!RunForm(FormName));
  2427.    }
  2428.  
  2429.  
  2430. /* TIW added 06-20-90 so functions can be called from fractals.c */
  2431. void init_misc()
  2432. {
  2433.    static struct ConstArg far vv[5];
  2434.    static union Arg argfirst,argsecond;
  2435.    if(!v) /* PB 901103 added this test to avoid clobbering the real thing */
  2436.       v = vv;  /* this is needed by lStkSqr and dStkSqr */
  2437.    Arg1 = &argfirst; Arg2 = &argsecond; /* needed by all the ?Stk* functions */
  2438.    fg = (double)(1L << bitshift);
  2439.    fgLimit = (double)0x7fffffffL / fg;
  2440.    ShiftBack = 32 - bitshift;
  2441.    Delta16 = bitshift - 16;
  2442.    bitshiftless1 = bitshift-1;
  2443.    uses_p1 = uses_p2 = uses_p3 = 0;
  2444. }
  2445.  
  2446. /* PB 910417 here to end changed.
  2447.     Allocate sub-arrays from one main farmemalloc, using global variable
  2448.     typespecific_workarea; calcfrac.c releases this area when calculation
  2449.     ends or is terminated.
  2450.     Moved the "f" array to be allocated as part of this.
  2451.     */
  2452.  
  2453. static void parser_allocate(void)
  2454. {
  2455.    /* CAE fp changed below for v18 */
  2456.    /* Note that XFRACT will waste about 6k here for pfls */
  2457.    /* Somewhat more memory is now allocated than in v17 here */
  2458.    /* however Store and Load were reduced in size to help make up for it */
  2459.  
  2460.    unsigned int f_size,Store_size,Load_size,v_size, p_size;
  2461.    free_workarea();
  2462.    f_size = sizeof(void(far * far *)(void)) * MAX_OPS;
  2463.    Store_size = sizeof(union Arg far *) * MAX_STORES;
  2464.    Load_size = sizeof(union Arg far *) * MAX_LOADS;
  2465.    v_size = sizeof(struct ConstArg) * MAX_ARGS;
  2466.    p_size = sizeof(struct fls far *) * MAX_OPS;
  2467.    typespecific_workarea =
  2468.    farmemalloc((long)(f_size+Load_size+Store_size+v_size+p_size));
  2469.    f = (void(far * far *)(void))typespecific_workarea;
  2470.    Store = (union Arg far * far *)(f + MAX_OPS);
  2471.    Load = (union Arg far * far *)(Store + MAX_STORES);
  2472.    v = (struct ConstArg far *)(Load + MAX_LOADS);
  2473.    pfls = (struct fls far *)(v + MAX_ARGS);
  2474.    uses_p1 = uses_p2 = uses_p3 = 0;
  2475. }
  2476.  
  2477. void free_workarea()
  2478. {
  2479.    if(typespecific_workarea) {
  2480.       farmemfree(typespecific_workarea);
  2481.       typespecific_workarea = NULL;
  2482.    }
  2483.    Store = (union Arg far * far *)0;
  2484.    Load = (union Arg far * far *)0;
  2485.    v = (struct ConstArg far *)0;
  2486.    f = (void(far * far *)(void))0;    /* CAE fp */
  2487.    pfls = (struct fls far * )0;   /* CAE fp */
  2488.  
  2489. }
  2490.